iT邦幫忙

2024 iThome 鐵人賽

DAY 21
0
Software Development

可以Go一輩子嗎?系列 第 21

Day21 內建套件介紹(一):time、strings, encoding

  • 分享至 

  • xImage
  •  

Day21 內建套件介紹(一):time、strings, encoding

經過這20天的學習,我們已經學會了Go的基礎概念,但如果想要實際進行運用的話就需要使用到Go的內建套件。今天我們就來介紹Go語言的一些內建套件,包括time、strings, encoding

time

Go語言的time套件提供了時間的相關操作,例如時間的格式化、時間的加減、時間的比較等等。下面是一些常用的time套件的方法

constant

  • Nanosecond Duration = 1
  • Microsecond = 1000 * Nanosecond
  • Millisecond = 1000 * Microsecond
  • Second = 1000 * Millisecond
  • Minute = 60 * Second
  • Hour = 60 * Minute

time.Sleep(d Duration)

這個函式可以讓程式暫停一段時間, 其中Duration代表的是時間的單位(在Go語言中,1 Duration等於1納秒)

time.Sleep(1 * time.Second) // 程式暫停1秒
time.Sleep(10 * time.Minute + 30 * time.Second) // 程式暫停10分30秒

順帶一題,Go很貼心的幫你把月份也定義成了常數,你只需要使用time.Januarytime.December就能夠取得對應的月份常數。

func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) Time

這個函式可以讓你基於日期與時間來建立一個Time物件(類似於Python的datetime)

XXXXAXMXX := time.Date(1999, time.April, 14, 0, 0, 0, 0, time.UTC)

你可以使用time.Now()來取得目前的時間,t.Date()來取得日期,t.Clock()來取得時間,t.Year()來取得年份,t.Month()來取得月份,t.Day()來取得日期,t.Hour()來取得小時,t.Minute()來取得分鐘,t.Second()來取得秒數,t.Nanosecond()來取得納秒數,t.Weekday()來取得星期幾,t.YearDay()來取得一年中的第幾天。

func (t Time) Add/Sub(d Duration) Time

透過Time物件的Add()與Sub()可以讓你Time物件進行時間的加減(類似於Python的timedelta)

now := time.Now()
nowInCST := now.Add(8 * time.Hour) // UTC+8
CSTInUTC := now.Sub(8 * time.Hour) // UTC

time.Since/Until(t Time) Time

用來計算時間差,Since()是用來計算從指定時間開始經過了多少時間,Until()是用來計算距離指定時間還有多少時間

UntilMidnight := time.Until(time.Date(now.Year(), now.Month(), now.Day(), 23, 59, 59, 0, time.Local))
SinceSunrise := time.Since(time.Date(now.Year(), now.Month(), now.Day(), 6, 0, 0, 0, time.Local))

time(t Time).Before/After/Equal(u Time) bool

用來比較兩個Time物件的大小,Before()是用來判斷是否在指定時間之前,After()是用來判斷是否在指定時間之後,Equal()是用來判斷是否相等

now := time.Now()
isAfterNoon := now.After(time.Date(now.Year(), now.Month(), now.Day(), 12, 0, 0, 0, time.Local))
isLateForSchool := now.Before(time.Date(now.Year(), now.Month(), now.Day(), 8, 0, 0, 0, time.Local))

time.Tick(d Duration) <-chan Time

透過這個函式可以讓你每隔一段時間從Channel中取得一個Time物件,這樣你就可以透過這個Channel來進行定時任務

// implement a bomb that will count down from 10:00 to 0:00
countdown := time.Date(now.Year(), now.Month(), now.Day(), 0, 10, 0, 0, time.Local)
for {
    select {
    case <-time.Tick(1 * time.Second):
        countdown = countdown.Add(-1 * time.Second)
        fmt.Printf("Time left: %v\n", countdown)
    }
    case <-time.After(10 * time.Minute):
        fmt.Println("Boom!")
        return
}

strings

Go語言的strings套件提供了對UTF-8字串的操作,例如字串的分割、合併、替換、大小寫轉換等等。下面是一些常用的strings套件的方法

strings.Compare(a, b string) int

用來比較兩個字串的大小,如果a < b則返回-1,如果a > b則返回1,否則返回0,常用於對slice of string進行排序

fmt.Println(strings.Compare("a", "b")) // -1
fmt.Println(strings.Compare("b", "a")) // 1
fmt.Println(strings.Compare("a", "a")) // 0

strings.Contains(s, substr string) bool

用來判斷字串s是否包含子字串substr,類似於Python的 substr in s

fmt.Println(strings.Contains("Hello, World!", "World")) // true
fmt.Println(strings.Contains("Hello, World!", "world")) // false

如果需要自己寫一個檢查字串中是否存在其中一個指定的字元(rune),可以使用strings.CompareFunc來自定義比較函式

f := func(r rune) bool {
    return r == 'a' || r == 'e' || r == 'i' || r == 'o' || r == 'u'
}
containVowel := strings.ContainsFunc("Hello, World!", f) // true
notContainVowel := strings.ContainsFunc("Hll, Wrld!", f) // false

HasPrefix/HasSuffix(s, prefix/suffix string) bool

用來判斷字串s是否以prefix/suffix開頭/結尾,類似於Python的 s.startswith(prefix)s.endswith(suffix)

fmt.Println(strings.HasPrefix("Hello, World!", "Hello")) // true
fmt.Println(strings.HasSuffix("Hello, World!", "World!")) // true

encoding

Go語言的encoding套件提供了對字串的編碼與解碼,例如base64、json、xml等等。目前encoding套件針對以下的編碼方式提供了支援
Image
下面是一些常用的encoding套件的方法(以JSON, XML, Base64為主)

JSON

  • json.Marshal(v interface{}) ([]byte, error): 將Go的struct或map等資料結構轉換成JSON格式的字串(struch需要是public, 且加入JSON tag)
type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}
p := Person{"John", 30}
b, err := json.Marshal(p)
fmt.Println(string(b)) // {"name":"John","age":30}

如果想加上縮排的話可以使用json.MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)

b, err := json.MarshalIndent(p, "", "    ")
fmt.Println(string(b)) // {
//     "name": "John",
//     "age": 30
// }
  • json.Unmarshal(data []byte, v interface{}) error: 將JSON格式的字串轉換成Go的struct或map等資料結構
var p Person
err := json.Unmarshal(b, &p)
fmt.Println(p) // {John 30}

XML

  • xml.Marshal(v interface{}) ([]byte, error): 將Go的struct或map等資料結構轉換成XML格式的字串(struch需要是public, 且加入XML tag)
type Person struct {
    Name string `xml:"name"`
    Age  int    `xml:"age"`
}
p := Person{"John", 30}
b, err := xml.Marshal(p)
fmt.Println(string(b)) // <Person><name>John</name><age>30</age></Person>
  • xml.Unmarshal(data []byte, v interface{}) error: 將XML格式的字串轉換成Go的struct或map等資料結構
var p Person
err := xml.Unmarshal(b, &p)
fmt.Println(p) // {John 30}

Base64

  • base64.StdEncoding.EncodeToString(data []byte) string: 將byte array轉換成Base64格式的字串,可用於傳輸二進制數據
// assume binaryData is a binary data
encodedDataStr := base64.StdEncoding.EncodeToString(binaryData)
fmt.Println(encodedDataStr)
  • base64.StdEncoding.DecodeString(s string) ([]byte, error): 將Base64格式的字串轉換成byte array
binaryContent, err := base64.StdEncoding.DecodeString(encodedDataStr)

那麼今天的文章就到這告一段落,如果我的文章有任何地方有錯誤請在留言區反應
明天將會介紹Go語言的其他內建套件
time

REF


上一篇
Day20. Module介紹與如何管理依賴 (go mod)
下一篇
Day22. 內建套件介紹(二):sort, io、os、net/http
系列文
可以Go一輩子嗎?31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言